import {
  ProForm,
  ProFormDependency,
  type ProFormInstance,
  type ProFormItemProps,
  type ProFormProps,
  type SubmitterProps
} from "@ant-design/pro-components";
import { useRequest } from "ahooks";
import {
  Input,
  Select,
  Radio,
  Checkbox,
  type InputProps,
  type RadioGroupProps,
  type SelectProps,
  AutoComplete,
  type AutoCompleteProps,
  Cascader,
  type CascaderAutoProps,
  type ColorPickerProps,
  ColorPicker,
  type DatePickerProps,
  DatePicker,
  type InputNumberProps,
  InputNumber,
  type RateProps,
  Rate,
  type SliderSingleProps,
  Slider,
  type SwitchProps,
  Switch,
  type TimePickerProps,
  TimePicker,
  type TreeSelectProps,
  TreeSelect,
  Col,
  Button
} from "antd";
import type { CheckboxGroupProps } from "antd/es/checkbox";
import { forwardRef, useImperativeHandle, useRef, type ReactNode } from "react";

// 定义选项类型
interface Option {
  value: string;
  label: string;
  children?: Option[];
}

// 定义基础表单项属性
type BaseColumnsProps = Omit<ProFormItemProps, "valueType" | "fieldProps">;

// 定义各种 valueType 对应的字段属性类型
interface TextItemProps extends BaseColumnsProps {
  valueType?: "text";
  fieldProps?: InputProps & Record<string, any>;
}

interface SelectItemProps extends BaseColumnsProps {
  valueType: "select";
  fieldProps?: SelectProps & Record<string, any>;
}

interface RadioItemProps extends BaseColumnsProps {
  valueType: "radio";
  fieldProps?: RadioGroupProps & Record<string, any>;
}

interface CheckboxItemProps extends BaseColumnsProps {
  valueType: "checkbox";
  fieldProps?: CheckboxGroupProps & Record<string, any>;
}

interface AutoCompleteItemProps extends BaseColumnsProps {
  valueType: "autoComplete";
  fieldProps?: AutoCompleteProps & Record<string, any>;
}

interface CascaderItemProps extends BaseColumnsProps {
  valueType?: "cascader";
  fieldProps?: CascaderAutoProps & Record<string, any>;
}

interface ColorPickerItemProps extends BaseColumnsProps {
  valueType?: "colorPicker";
  fieldProps?: ColorPickerProps & Record<string, any>;
}

interface DatePickerItemProps extends BaseColumnsProps {
  valueType?: "datePicker";
  fieldProps?: DatePickerProps & Record<string, any>;
}

interface InputNumberItemProps extends BaseColumnsProps {
  valueType?: "inputNumber";
  fieldProps?: InputNumberProps & Record<string, any>;
}

interface RateItemProps extends BaseColumnsProps {
  valueType?: "rate";
  fieldProps?: RateProps & Record<string, any>;
}

interface SliderItemProps extends BaseColumnsProps {
  valueType?: "slider";
  fieldProps?: SliderSingleProps & Record<string, any>;
}

interface SwitchItemProps extends BaseColumnsProps {
  valueType?: "switch";
  fieldProps?: SwitchProps & Record<string, any>;
}

interface TimePickerItemProps extends BaseColumnsProps {
  valueType?: "timePicker";
  fieldProps?: TimePickerProps & Record<string, any>;
}

interface TreeSelectItemProps extends BaseColumnsProps {
  valueType?: "TreeSelect";
  fieldProps?: TreeSelectProps & Record<string, any>;
}

// 联合所有字段类型
type TypedColumnsProps =
  | TextItemProps
  | SelectItemProps
  | RadioItemProps
  | CheckboxItemProps
  | AutoCompleteItemProps
  | CascaderItemProps
  | ColorPickerItemProps
  | DatePickerItemProps
  | InputNumberItemProps
  | RateItemProps
  | SliderItemProps
  | SwitchItemProps
  | TimePickerItemProps
  | TreeSelectItemProps;

// 扩展字段属性，添加请求相关功能
type ExtendedColumnsProps = TypedColumnsProps & {
  params?: Record<string, unknown>;
  request?: (params: Record<string, unknown>) => Promise<Option[]>;
  dependencies?: string[];
  handFormItem?: (
    values: Record<string, unknown>,
    form: ProFormInstance
  ) => Partial<ExtendedColumnsProps> | void;
};

// 定义表单基础属性，排除 submitter
interface BaseMFormProps extends Omit<ProFormProps, "submitter"> {
  columns?: ExtendedColumnsProps[];
}

// 定义 grid 模式下的 submitter 类型
type GridSubmitter =
  | boolean
  | ((dom: ReactNode[], form: ProFormInstance) => ReactNode[]);

// 定义非 grid 模式下的 submitter 类型
type NonGridSubmitter = SubmitterProps | ((dom: ReactNode[]) => ReactNode[]);

// 根据 grid 属性区分两种不同的表单属性类型
interface MFormPropsWithGrid extends BaseMFormProps {
  grid: true;
  submitter?: GridSubmitter;
}

interface MFormPropsWithoutGrid extends BaseMFormProps {
  grid?: false;
  submitter?: NonGridSubmitter;
}

// 使用联合类型组合两种情况
type MFormProps = MFormPropsWithGrid | MFormPropsWithoutGrid;

// 组件实现
export default forwardRef(function MForm(
  props: MFormProps,
  ref: React.Ref<ProFormInstance>
) {
  // 渲染不同类型输入组件的函数
  const ValueTypeRender = ({
    item,
    value,
    onChange
  }: {
    item: ExtendedColumnsProps;
    value?: unknown;
    onChange?: any;
  }) => {
    // 获取字段类型，默认为 text
    const valueType = item.valueType || "text";

    // 统一处理字段属性
    const fieldProps = {
      value,
      onChange,
      ...(item.fieldProps || {})
    };

    // 如果有远程数据请求，则获取数据
    const { data = [] } = useRequest(
      async () => {
        if (item.request) {
          return await item.request(item.params || {});
        }
        return [];
      },
      {
        refreshDeps: [JSON.stringify(item.params)]
      }
    );

    // 根据 valueType 渲染对应的组件
    switch (valueType) {
      case "select":
        return <Select {...(fieldProps as SelectProps)} options={data} />;
      case "radio":
        return (
          <Radio.Group {...(fieldProps as RadioGroupProps)} options={data} />
        );
      case "checkbox":
        return (
          <Checkbox.Group
            {...(fieldProps as CheckboxGroupProps)}
            options={data}
          />
        );
      case "autoComplete":
        return <AutoComplete {...(fieldProps as AutoCompleteProps)} />;
      case "cascader":
        return (
          <Cascader {...(fieldProps as CascaderAutoProps)} options={data} />
        );
      case "colorPicker":
        return <ColorPicker {...(fieldProps as ColorPickerProps)} />;
      case "datePicker":
        return <DatePicker {...(fieldProps as DatePickerProps)} />;
      case "inputNumber":
        return <InputNumber {...(fieldProps as InputNumberProps)} />;
      case "rate":
        return <Rate {...(fieldProps as RateProps)} />;
      case "slider":
        return <Slider {...(fieldProps as SliderSingleProps)} />;
      case "switch":
        return <Switch {...(fieldProps as SwitchProps)} />;
      case "timePicker":
        return <TimePicker {...(fieldProps as TimePickerProps)} />;
      case "TreeSelect":
        return (
          <TreeSelect {...(fieldProps as TreeSelectProps)} treeData={data} />
        );
      default:
        return <Input {...(fieldProps as InputProps)} />;
    }
  };

  const formRef = useRef<ProFormInstance>(null);
  useImperativeHandle(ref, () => formRef.current as ProFormInstance);

  // 确定 submitter 属性
  const getSubmitter = (): false | SubmitterProps | undefined => {
    if ("grid" in props && props.grid) {
      return false;
    }
    return props.submitter as SubmitterProps | undefined;
  };

  return (
    <ProForm {...props} submitter={getSubmitter()} formRef={formRef}>
      {props.columns
        ? props.columns.map((item) => (
            <ProFormDependency
              name={item.dependencies ?? []}
              key={(item as any).name}
            >
              {(values, form) => {
                const handFormProps = item.handFormItem?.(values, form) ?? {};
                const mergedItem = {
                  ...item,
                  ...handFormProps
                } as ExtendedColumnsProps;

                return "grid" in props && props.grid ? (
                  <Col
                    span={
                      "colSize" in mergedItem &&
                      typeof mergedItem.colSize === "number"
                        ? mergedItem.colSize *
                          ("colProps" in props &&
                          typeof props.colProps?.span === "number"
                            ? props.colProps?.span
                            : 1)
                        : ("colProps" in props && props.colProps?.span) ||
                          undefined
                    }
                    {...("colProps" in item
                      ? { ...item.colProps, ...handFormProps }
                      : { ...handFormProps })}
                  >
                    <ProForm.Item {...mergedItem}>
                      <ValueTypeRender
                        item={mergedItem}
                        value={mergedItem?.fieldProps?.value}
                        onChange={mergedItem?.fieldProps?.onChange}
                      />
                    </ProForm.Item>
                  </Col>
                ) : (
                  <ProForm.Item {...mergedItem}>
                    <ValueTypeRender
                      item={mergedItem}
                      value={mergedItem?.fieldProps?.value}
                      onChange={mergedItem?.fieldProps?.onChange}
                    />
                  </ProForm.Item>
                );
              }}
            </ProFormDependency>
          ))
        : (props.children as React.ReactNode)}

      {"grid" in props && props.grid && props.submitter !== false && (
        <div className="flex gap-[8px] px-[12px]">
          {typeof props.submitter === "function" ? (
            props.submitter(
              [
                <Button type="primary" htmlType="submit" key="submit">
                  提交
                </Button>,
                <Button htmlType="reset" key="reset">
                  重置
                </Button>
              ],
              formRef.current as ProFormInstance
            )
          ) : (
            <>
              <Button type="primary" htmlType="submit">
                提交
              </Button>
              <Button htmlType="reset">重置</Button>
            </>
          )}
        </div>
      )}
    </ProForm>
  );
});
